#pragma once

namespace AVUI {

class BaseArray : public Object
{
public:
    DECLARE_ELEMENT(BaseArray, Object);
};

template<class T>
class TArray : public BaseArray
{
public:
    TArray(unsigned int capacity) : m_capacity(capacity)
    {
        m_rgValues = new T[capacity];
    }

    ~TArray()
    {
        delete[] m_rgValues;
    }

    T& operator[](int index)
    {
        if(index >= (int)m_capacity)
        {
            LibraryCriticalError();
        }
        return m_rgValues[index];
    }

    const T& operator[](int index) const
    {
        if(index >= (int)m_capacity)
        {
            LibraryCriticalError();
        }
        return m_rgValues[index];
    }

    int get_Length() const { return m_capacity; }

private:
    T* m_rgValues;
    unsigned int m_capacity;
};

template < class T >
class TArrayPtr : public TRefCountedPtr< TArray<T> >
{
public:
    TArrayPtr() : TRefCountedPtr() { }
    TArrayPtr(TArray<T>* p, bool addRef = true) : TRefCountedPtr(p, addRef) { }
    TArrayPtr(const TArrayPtr< TArray<T> >& other) : TRefCountedPtr(other) { }

    const T& operator [] (int i) const { return (*get_Ptr())[i]; }
    T& operator [] (int i) { return (*get_Ptr())[i]; }
};

template<class T>
TArrayPtr<T> array_allocate(unsigned int len)
{
    TArrayPtr<T> pT(new TArray<T>(len), false);

    return pT;
}


};
